package com.taxi.driver.module.order.popup;

import android.os.Handler;
import android.text.TextUtils;

import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.model.LatLng;
import com.qianxx.network.RequestError;
import com.qianxx.utils.RxUtil;
import com.socks.library.KLog;
import com.taxi.driver.R;
import com.taxi.driver.common.BasePresenter;
import com.taxi.driver.config.BizStatus;
import com.taxi.driver.config.OrderStatus;
import com.taxi.driver.config.PositionType;
import com.taxi.driver.config.TimeType;
import com.taxi.driver.data.order.OrderRepository;
import com.taxi.driver.data.user.UserRepository;
import com.taxi.driver.event.OrderEvent;
import com.taxi.driver.module.vo.OrderVO;
import com.taxi.driver.socket.SocketEvent;
import com.taxi.driver.socket.SocketPushContent;
import com.taxi.driver.util.SpeechUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import rx.Observable;

/**
 * 功能描述：
 */
public class OrderPopupPresenter extends BasePresenter implements OrderPopupContract.Presenter {

    private OrderPopupContract.View mView;
    private OrderRepository mOrderRepository; //订单仓库
    private UserRepository mUserRepository; //用户仓库
    private String mOrderUuid = ""; //当前订单编号

    private boolean mIsGrabing; //true－正在抢单，等待结果返回
    private boolean isRessign;//是否是改派订单或指派订单

    @Inject
    public OrderPopupPresenter(OrderPopupContract.View view, OrderRepository orderRepository, UserRepository userRepository) {
        mView = view;
        mOrderRepository = orderRepository;
        mUserRepository = userRepository;
    }

    @Override
    public void subscribe() {
        super.subscribe();
        EventBus.getDefault().register(this);
        mIsGrabing = false;

        // 判断是否要隐藏忽略订单
        mOrderRepository.ignoreList()
                .switchIfEmpty(Observable.error(new Throwable("no element")))
                .filter(strings -> {
                    for (String string : strings) {
                        if (string.equals(mOrderUuid)) {
                            return true;
                        }
                    }
                    return null;
                })
                .compose(RxUtil.applySchedulers())
                .subscribe(KLog::e, KLog::e, () -> mView.hideIgnore());
    }

    @Override
    public void unsubscribe() {
        super.unsubscribe();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void setOrderUuid(String orderUuid) {
        mOrderUuid = orderUuid;
    }

    @Override
    public String getOrderUuid() {
        return mOrderUuid;
    }

    @Override
    public void orderDetail() {
        mSubscriptions.add(
                mOrderRepository.reqOrderDetail(mOrderUuid, true)
                        .map(OrderVO::createFrom)
                        .compose(RxUtil.applySchedulers())
                        .subscribe(vo -> {
                            if (vo.mainStatus == 5) {
                                if (vo.subStatus == OrderStatus.CANCEL_BY_SYSTEM) {
                                    orderInvalid("订单已由后台关闭");
                                } else {
                                    orderInvalid("订单已被乘客取消");
                                }
                            } else {
                                LatLng curLatLng = (vo.typeTime == TimeType.REALTIME || vo.typeTime == TimeType.DAILY_RENT
                                        || vo.typeTime == TimeType.HALF_DAY_RENT) ? mUserRepository.getLatLng() : null;
                                mView.setOrderInfo(vo, curLatLng); //等待应答，设置显示
                                String[] reportSplit = vo.report.split("#");
                                DecimalFormat df = new DecimalFormat("0.00");
                                if (reportSplit.length > 1) {
                                    double distance = AMapUtils.calculateLineDistance(curLatLng, vo.getOriginLatLng());
                                    if (distance > 1000) {
                                        distance = distance / 1000;//换算成公里
                                        reportNewOrder(reportSplit[0] + df.format(distance) + "公里" + reportSplit[1]); //播报新订单
                                    } else {
                                        reportNewOrder(reportSplit[0] + df.format(distance) + "米" + reportSplit[1]); //播报新订单
                                    }
                                } else {
                                    reportNewOrder(reportSplit[0]);
                                }
                            }
                        }, ex -> {
                            if (ex instanceof RequestError && ((RequestError) ex).getErrCode() == 20001) {
                                orderInvalid("订单已被其他司机抢走");
                            } else {
                                showNetworkError(ex, R.string.network_error, mView, mUserRepository);
                            }
                        }));
        // 开启定时
        mHandler.postDelayed(mTimerRun, 1000);
    }

    @Override
    public void grabOrder() {
        //如果当前正在执行抢单接口就不允许反复抢单(防抖动点击)
        if (mIsGrabing)
            return;

        mIsGrabing = true;
        mSubscriptions.add(
                mOrderRepository.reqGrab(mOrderUuid)//抢单
                        .map(OrderVO::createFrom)
                        .throttleFirst(500, TimeUnit.MILLISECONDS)
                        .compose(RxUtil.applySchedulers())
                        .subscribe(vo -> {
                            SpeechUtil.speech(mView.getContext(), R.string.speech_order_grab_success); //播报抢单成功
                            mView.grabSuccess(mOrderUuid); //执行相应操作
                            // 发送司机位置（司机抢单）
                            EventBus.getDefault().post(new SocketEvent(SocketEvent.SEND_POSITION, BizStatus.ORDER_RECEIVING, PositionType.DDPD, mOrderUuid));
                            if (vo.subStatus == 210) {
                                EventBus.getDefault().post(new SocketEvent(SocketEvent.SEND_POSITION, BizStatus.CARRY_PASSENGERS, PositionType.SJCF, mOrderUuid));
                            }
                        }, ex -> {
                            // 抢单失败相关处理
                            if (ex instanceof RequestError) {
                                RequestError error = (RequestError) ex;
                                switch (error.getErrCode()) {
                                    case 1001:
                                    case 1002:
                                    case 1003:
                                    case 1100:
                                        grabFail("订单失效", error.getMessage());
                                        break;
                                    case 1004:
                                        grabFail("订单冲突", error.getMessage());
                                        break;
                                    default:
                                        showNetworkError(ex, R.string.network_error, mView, mUserRepository);
                                        break;
                                }
                            } else {
                                showNetworkError(ex, R.string.network_error, mView, mUserRepository);
                            }
                        }));
    }

    @Override
    public int driverType() {
        return mUserRepository.getDriverType();
    }

    @Override
    public void ignoringOrder() {
        EventBus.getDefault().post(new OrderEvent(OrderEvent.IGNORE_ORDER, mOrderUuid));
        mOrderRepository.ignoringOrder(mOrderUuid);
    }

    @Override
    public void onDestory() {
        mHandler.removeCallbacks(mTimerRun); //关闭定时
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onOrderEvent(OrderEvent event) {
        switch (event.type) {
            case OrderEvent.ORDER_DISTRIBUTE: {
                SpeechUtil.stop(mView.getContext());
                if (event.obj1 == null) return;
                SocketPushContent content = (SocketPushContent) event.obj1;
                mOrderUuid = content.orderUuid;
                mTime = 3;
                mBufferStatus = 0;
                mView.setAssign();
                orderDetail();
                break;
            }
            case OrderEvent.ORDER_PASSENGER_CANCEL:
            case OrderEvent.ORDER_MATCH_THE_TIMEOVER:
                // 乘客已取消订单（服务端暂时没推送）
            case OrderEvent.ORDER_CLOSE:
                // 后台关闭订单
            case OrderEvent.ORDER_HAS_BEEN_ROBBED: {
                // 该订单已被抢
                if (event.obj1 == null) return;
                SocketPushContent content = (SocketPushContent) event.obj1;
                if (!mOrderUuid.equals(content.data.orderUuid)) return;
                orderInvalid(content.data.content);
                break;
            }
        }
    }

    private void grabFail(String title, String failReason) {
        mHandler.removeCallbacks(mTimerRun);
        SpeechUtil.speech(mView.getContext(), failReason); //播报语音
        mTime = BUFFER_TIME; //缓冲3秒
        mBufferStatus = 2; //状态切换为抢单失败
        mView.grabFail(mTime, title, failReason); //更新显示，按键不可点击
        mHandler.postDelayed(mTimerRun, 1000);
    }

    private void orderInvalid(String invalid) {
        mHandler.removeCallbacks(mTimerRun);
        SpeechUtil.speech(mView.getContext(), invalid); //播报语音
        mTime = BUFFER_TIME; //缓冲3秒
        mBufferStatus = 3; //切换状态为失效
        mView.orderInvalid(mTime, invalid); //更新显示，按键不可点击
        mHandler.postDelayed(mTimerRun, 1000);
    }

    private void reportNewOrder(String report) {
        if (TextUtils.isEmpty(report)) {
            SpeechUtil.speech(mView.getContext(), R.string.speech_order_new);
        } else {
            SpeechUtil.speech(mView.getContext(), report);
        }
    }

    /* ************ 以下用于实现定时器 ************ */

    /**
     * 0－(3秒缓冲时间)
     * 1－(15秒可抢单时间)
     * 2-(抢单失败 或 订单失效 3秒缓冲时间)
     */
    private final static int BUFFER_TIME = 3; //缓冲3秒
    private final static int GRAG_TIME = 15; //可抢时间15秒

    private int mTime = BUFFER_TIME;
    private int mBufferStatus; //按键状态

    private Handler mHandler = new Handler();

    private Runnable mTimerRun = new Runnable() {
        @Override
        public void run() {
            mHandler.removeCallbacks(mTimerRun);

            mTime--; //时间减1
            if (mTime <= 0) {
                switch (mBufferStatus) {
                    case 0: //3秒缓冲时间一到
                        mTime = GRAG_TIME; //倒计时切换为15秒
                        mBufferStatus = 1; //状态切换为"可抢"状态
                        break;
                    case 1:
                        mTime = 0;
                        if (!mIsGrabing) { //非抢单状态，关闭界面
                            mView.showBuffering(0, mBufferStatus);
                            mView.closeActivity();
                            return;
                        }
                        break;
                    case 2:
                        mTime = 0;
                        mView.showBuffering(0, mBufferStatus);
                        mView.closeActivity();
                        break;
                    case 3:
                        mTime = 0;
                        mView.showBuffering(0, mBufferStatus);
                        mView.closeActivity();
                        break;
                }
            }
            mView.showBuffering(mTime, mBufferStatus); //更新显示

            mHandler.postDelayed(mTimerRun, 1000);
        }
    };
}
